<template>
  <div class="bomView">
    <div class="bomView-title">
      <div class="bomView-title-select">
        <span>{{$t('common.bomUsageVersion')}}</span>
        <el-select v-model="bomId"
                   @change="changePurVersion">
          <el-option v-for="item in purVersionOption"
                     :key="item.bomId"
                     :label="`${item.usagesName}/${item.versionNo}`"
                     :value="item.bomId"></el-option>
        </el-select>
      </div>
    </div>
    <el-tree ref="tree"
             :props="defaultProps"
             :data="data"
             @node-expand="expand"
             :empty-text="$t('common.pleaseChooseBomUsageVersion')">
      <span class="custom-tree-node"
            slot-scope="{ node,data }">
        <span>
          <i class="el-icon-setting"
             style="margin-right:5px"></i>
          <span>{{ node.label }}</span>
          <span v-if="data.isVariant && !data.hasData">
            <el-tooltip :enterable="false"
                        placement="top"
                        :content="$t('common.edit')">
              <el-button type="text"
                         icon="el-icon-edit"
                         @click="editBom(data,node)"></el-button>
            </el-tooltip>
          </span>
        </span>
      </span>
    </el-tree>
    <el-dialog :title="title"
               width="50%"
               :close-on-click-modal="false"
               :close-on-press-escape="false"
               append-to-body
               :before-close="close"
               :visible.sync="visible">
      <avue-crud class="psCrud"
                 style="height: 300px;"
                 :option="option"
                 :data="tableData"
                 :table-loading="loading">
        <template slot="fieldName"
                  slot-scope="{row}">
          <span :class="{'isRequired':row.isRequired}">{{row.fieldName}}</span>
        </template>
        <template slot="fieldVal"
                  slot-scope="{row}">
          <customFieldsToClass v-model="row.fieldVal"
                               :form="row"
                               @change="changeCFTC(row)"
                               :checkData="tableData"
                               :checkRules="checkRules"
                               :configRules="configRules"
                               :validTime="row.validTime"
                               :isValid="true"
                               :isDefault="false"></customFieldsToClass>
        </template>
        <template slot="message"
                  slot-scope="{row}">
          <span style="color:red">{{row.message}}</span>
        </template>
      </avue-crud>
      <span slot="footer"
            class="dialog-footer">
        <el-button type="primary"
                   @click="confirmView">{{$t('common.save')}}</el-button>
        <el-button @click="close">{{$t('common.cancel')}}</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { option } from './productSelection'
import { getBom, getBomListByMaterialId, getVariantClassData, checkConfigure, getVariantTableClassId, getCharacterConfigureClassId, getOperator } from '../../api/setting/productSelection'
import customFieldsToClass from '../customFieldsToClass'

export default {
  components: { customFieldsToClass },
  data () {
    return {
      option: option(this),
      loading: false,
      tableData: [],
      defaultProps: {
        children: 'children',
        label: 'label',
        isLeaf: 'leaf'
      },
      bomId: '',
      data: [],
      purVersionOption: [],
      checkRules: [],
      configRules: [],
      operators: [],
      index: 0,
      title: '',
      visible: false,
      isCanResult: false,
      tableName: 'erp_material_base',
      currentNode: {},
      currentData: {}
    }
  },
  props: {
    root: {
      type: Array,
      required: true
    },
    productId: {
      type: [Number, String],
      required: true
    },
    factoryId: {
      type: Number,
      required: true
    }
  },
  watch: {
    root: {
      deep: true,
      handler () {

      }
    },
    productId: {
      immediate: true,
      handler: 'getBomListByMaterialId'
    }
  },
  mounted () {
    this.getDict()
  },
  methods: {
    getDict () {
      getOperator().then(res => {
        this.operators = res.data.data
      })
    },
    changeCFTC (row) {
      let flag = false
      this.tableData.some(res => {
        if (this.validatenull(res.fieldVal)) {
          flag = true
          return true
        }
      })
      if (flag) this.tableData.some((res, index) => {
        res.validTime = new Date().getTime()
      })
      else checkConfigure(this.tableData.map(res => {
        return {
          characterId: res.characterId,
          fieldName: res.fieldName,
          val: res.fieldVal
        }
      }), row.classId).then(res => {
        const data = res.data.data
        const characterIds = this.tableData.map(res => res.characterId)
        this.tableData.some(res => {
          let message = []
          data.resultList.some(res2 => {
            if (res2.characterId === res.characterId) {
              message.push(`${res.fieldName}应${this.getOperatorName(res2.operator)}${res2.attributeValue}`)
              return true
            }
          })
          if (data.returnCharacterIdList && data.returnCharacterIdList.indexOf(res.characterId) !== -1) message.push(res.fieldName + '不符合变式表相关性')
          this.isCanResult = message.length > 0
          this.$set(res, 'message', message.join('  |  '))
        })
      })
    },
    getOperatorName (operator) {
      let result = ''
      this.operators.some(res => {
        if (operator === res.code) {
          result = res.name
          return true
        }
      })
      return result
    },
    confirmView () {
      if (this.tableData.length === 0) {
        this.$message.warning(this.$t('common.selectProduct'))
        return
      }
      let flag = false
      this.tableData.some(res => {
        if (this.validatenull(res.fieldVal)) {
          flag = true
          return true
        }
      })
      if (flag) {
        this.$message.warning(this.$t('common.pleaseFullAttrValue'))
        return
      }
      if (this.isCanResult) {
        this.$message.warning(this.$t('common.validationFailed'))
        return
      }
      this.currentNode.data.selfCharacterList = this.tableData.map(res => {
        return {
          characterId: res.characterId,
          fieldName: res.fieldName,
          val: res.fieldVal
        }
      })
      this.loadNode(this.currentNode, (res) => {
        this.parseData(this.data, res, this.currentData.index)
        this.close()
      })
    },
    close () {
      this.visible = false
      console.log(this.$refs.tree)
    },
    getBomListByMaterialId () {
      if (!this.productId || !this.factoryId) {
        console.error('配置错误、检查productId,factoryId是否传参');
        return
      }
      getBomListByMaterialId(this.factoryId, this.productId).then(res => {
        this.purVersionOption = res.data.data
      })
    },
    editBom (data, node) {
      this.loadRules(data, node, true)
    },
    expand (data, node) {
      if (data.isVariant && data.hasData) {
        this.loadRules(data, node)
        return
      }
      if (data.hasData) this.loadNode(node, (res) => {
        this.parseData(this.data, res, data.index)
      })
    },
    loadRules (data, node, edit) {
      this.currentNode = node
      this.currentData = data
      this.title = data.label
      let params = 0
      this.isCanResult = false
      this.visible = true
      getVariantClassData(0, data.materialId, this.tableName).then(res => {
        const data = res.data.data
        params = data[0].id
        if (Array.isArray(data) && data.length > 0) this.tableData = data[0].characterDataList.map(res => {
          return {
            ...res,
            fieldVal: edit ? data.selfCharacterList.filter(res2 => res.characterId === res2.characterId)[0].val : ''
          }
        })
        let index = 0
        let flag = ''
        let timer = setInterval(() => {
          this.loading = sessionStorage.getItem('getData') !== 'false'
          if (flag === sessionStorage.getItem('getData')) index++
          else {
            flag = sessionStorage.getItem('getData')
            index = 0
          }
          if (index === 3000) clearInterval(timer)
        }, 1);
        return getVariantTableClassId(params)
      }).then(res => {
        const data = res.data.data
        const result = []
        data.some(res2 => {
          const order = res2.fieldList.map(res => res.characterId)
          res2.rowList.some(res3 => {
            const item = {}
            order.some((res4, index) => {
              item[res4] = res3[index]
            })
            result.push(item)
          })
        })
        this.checkRules = result
        return getCharacterConfigureClassId(params)
      }).then(res => {
        if (res.data.data.length > 0) this.configRules = res.data.data.map(res => res.characterConfigureList).reduce((pre, next) => { return pre.concat(next) })
        else this.configRules = []
      })
    },
    parseData (list, result, index) {
      if (Array.isArray(list))
        list.some(res => {
          if (res.index === index) {
            res.hasData = false
            res.children = result
            return true
          }
          if (res.children && res.children.length > 0) this.parseData(res.children, result, index)
        })
    },
    changePurVersion () {
      this.$nextTick(() => {
        this.index = 0
        this.loadNode(undefined, (data) => {
          this.data = data
        })
      })
    },
    loadNode (node, resolve) {
      if (!this.bomId) {
        resolve([])
        return
      }
      if (!node) node = { level: 0 }
      const params = {
        bomId: node.level > 1 ? node.data.bomId : this.bomId,
        parentCharacterList: node.level > 1 ? node.parent.data.selfCharacterList : this.root,
        rootCharacterList: this.root,
        selfCharacterList: node.level > 1 ? node.data.selfCharacterList : this.root
      }
      getBom(params).then(res => {
        const data = res.data.data
        if (data)
          if (node.level === 0) resolve([{
            label: `${data.materialName}（${this.$t('advancedConfig.id')}：${data.materialNo},${this.$t('material.description')}：${data.description || ''},${this.$t('material.model')}：${data.model || ''},${this.$t('accountBegin.beginQuantity')}：${res.num || ''},${this.$t('basicData.unitName')}：${data.unitName || ''}）`, selfCharacterList: data.characterList, bomId: data.bomId, index: this.index++, materialId: data.materialId, children: data.children.map(res => {
              const result = { label: `${res.materialName}（${this.$t('advancedConfig.id')}：${res.materialNo},${this.$t('material.description')}：${res.description || ''},${this.$t('material.model')}：${res.model || ''},${this.$t('accountBegin.beginQuantity')}：${res.num || ''},${this.$t('basicData.unitName')}：${res.unitName || ''}）`, selfCharacterList: res.characterList, bomId: res.bomId, index: this.index++, materialId: res.materialId, hasData: !!res.bomId, isVariant: res.typeIdCode === '05' }
              if (res.bomId) result.children = [{}]
              return result
            })
          }])
          else resolve(data.children.map(res => {
            const result = { label: `${res.materialName}（${this.$t('advancedConfig.id')}：${res.materialNo},${this.$t('material.description')}：${res.description || ''},${this.$t('material.model')}：${res.model || ''},${this.$t('accountBegin.beginQuantity')}：${res.num || ''},${this.$t('basicData.unitName')}：${res.unitName || ''}）`, selfCharacterList: res.characterList, bomId: res.bomId, index: this.index++, materialId: res.materialId, hasData: !!res.bomId, isVariant: res.typeIdCode === '05' }
            if (res.bomId) result.children = [{}]
            return result
          }))
      })
    },
  }
}
</script>

<style lang="scss" scoped>
.bomView {
  &-title {
    margin-bottom: 10px;
    &-select {
      display: flex;
      flex-flow: row nowrap;
      align-items: center;
      justify-content: flex-start;
      & > span {
        margin-right: 10px;
      }
    }
  }
}
.psCrud {
  /deep/.avue-crud__menu {
    display: none;
  }
  .isRequired {
    &::before {
      content: "*";
      color: red;
      font-size: 18px;
    }
  }
}
</style>